#!/bin/bash
# 项目编译
# 切换代码页到UTF-8
#chcp.com 65001 > /dev/null

sh_folder=$(dirname $(readlink -f $0))
pushd $sh_folder > /dev/null

[ -z "$(which git 2>/dev/null )" ] && echo "not found git" && exit 255

# 修改$1指定的文件名中名为$2的值为$3
# $1 key=value格式保存变量值的文件名
# $2 变量名key
# $3 变量的值value
# 修改成功返回0, 失败退出脚本,$1 文件不存在则创建文件并添加key=value
function set_value(){
    if [ ! -f "$1" ]
    then 
        # 添加key=value对到文件
        echo -e "\n$2=$3" >> $1 || exit 255
        return 0
    fi
    if grep -q -E "^\s*$2\s*=.+\$" $1
    then
        # 如果存在key=value定义，则修改定义,否则向文件添加定义
        sed -i -r "s!(^\s*$2\s*=).*\$!\\1$3!" $1 || exit 255
        return 0
    else
        # 添加key=value对到文件
        echo -e "\n$2=$3" >> $1 || exit 255
        return 0
    fi
    
}

# 编译maven项目
# $1 git项目源码位置
# $2 项目源码git分支名
# $3 要执行的编译命令
function maven_build(){
    pushd "$1" > /dev/null || exit 255
    # 切换到指定分支
    checkou_to_branch $2 || exit 255
    # 执行编译指令
    $3 || exit 255
    local code=$?
    # 切换到原分支
    checkou_to_branch $checkou_to_branch_return || exit 255
    popd > /dev/null || exit 255
    [ $code -ne 0 ] && exit 255
}
# 基于vue的web端项目编译
# $1 git项目源码位置
# $2 项目源码git分支名
# $3 要执行的编译命令
function vue_build(){
    pushd "$1" > /dev/null || exit 255
    # 切换到指定分支
    checkou_to_branch $2 || exit 255
    if [ ! -d "$1/node_modules" ]
    then
        pushd "$1" >/dev/null 2>&1 || exit 255
        npm install || exit 255
        popd >/dev/null 2>&1 || exit 255
    fi
    # 执行编译指令
    $3 || exit 255
    local code=$?    
    # 切换到原分支
    checkou_to_branch $checkou_to_branch_return || exit 255
    popd > /dev/null || exit 255
    [ $code -ne 0 ] && exit 255
}

# 判断指定$1的文件夹是否为一个git 仓库,是返回0，否则返回非0
# $1 git项目源码位置，为空返回1
function is_git_repo(){
    [ -d "$1" ] && git --git-dir "$1/.git" --work-tree "$1" status >/dev/null 2>&1
}
# 判断指定$1的文件夹是否为一个git 仓库,是返回0，否则返回退出脚本
# $1 git项目源码位置
function check_git_repo(){
    [ -d "$1" ] || { echo "ERROR:[$1]文件夹不存在" && exit 255; }
    is_git_repo "$1" || { echo "ERROR:[$1]不是git仓库文件夹" && exit 255; }    
}
# 返回$1指定的git项目的当前分支(branch)或标签名(tag)
# $1 git项目源码位置,为空获则默认为当前文件夹
function current_branch () {
    local folder="$(pwd)"
    [ -n "$1" ] && folder="$1"
    git --git-dir "$folder/.git" --work-tree "$folder" rev-parse --abbrev-ref HEAD | grep -v HEAD || \
    git --git-dir "$folder/.git" --work-tree "$folder" describe --tags HEAD || \
    git --git-dir "$folder/.git" --work-tree "$folder" rev-parse HEAD
}
# 切换到$2指定分支(branch)或标签名(tag)
# $1 分支/tag名
# $2 git项目源码位置,为空获则默认为当前文件夹
# checkou_to_branch_return 变量保存切换前的分支名
function checkou_to_branch(){
    [ -z "$1" ] && echo "ERROR:\$1 分支名参数为空" && exit 255
    local folder="$(pwd)"
    [ -n "$2" ] && folder="$2"
    checkou_to_branch_return="$(current_branch "$folder")"
    [ "$checkou_to_branch_return" = "$1" ] && return 0
    git --git-dir "$folder/.git" --work-tree "$folder" checkout "$1" >/dev/null 2>&1 || exit 255
}

# 提示输入$1指定的项目的分支名
# $input_branch_return变量返回有效分支名,默认master
# 输入无效的分支名导致退出
# $1 git项目源码位置
function input_branch(){
    input_branch_return=$(current_branch "$1")
    read -p "请输入$(basename $1)项目的分支(branch)或标签(tag)名(默认$input_branch_return):" input_str
    [ -n "$input_str" ] && input_branch_return=$input_str
    input_branch_return=${input_branch_return// /}
    [ -z "$(git --git-dir "$1/.git" --work-tree "$1" branch -a| grep -w $input_branch_return)" ] && \
    [ -z "$(git --git-dir "$1/.git" --work-tree "$1" tag | grep -w $input_branch_return)" ] && echo "无效的分支或标签名 [$input_branch_return]" && exit 255
}

# 返回$1指定的maven项目的版本号
# $1 maven项目源码位置
# $2 项目分支名,不为空时先切换到指定分支再调用mvn获取版本号
function pom_version(){
    #mvn -f $1/pom.xml -Dexec.executable='echo' -Dexec.args='${project.version}' --non-recursive exec:exec -q 
    mvn -f $1/pom.xml org.apache.maven.plugins:maven-help-plugin:3.2.0:evaluate -Dexpression=project.version -q -DforceStdout
}

# 返回$1指定的node项目的版本号
# $1 node项目源码位置
function node_prj_version(){
    grep -P '"version"\s*:\s*"\S+"' $1/package.json | sed -e 's/"version"\s*://' -e 's/\s*//g' -e 's/[",]//g' 2>&1
}

# 复制$1指定的facelog项目编译后的文件到当前项目文件夹
# $1 facelog项目源码位置
# $2 项目版本号
function facelog_copy(){
    local pushd_bash=1
    [ -d bash ] && pushd bash >/dev/null && pushd_bash=0
    local folder="facelog-service"
    # 从pom.xml中获取版本号
    local project_version=$2
    rm -fr "$folder" || exit 255
    if [ ! -d "$folder/target" ]
    then
        mkdir -p "$folder/target" || exit 255
    fi
    local jar_file="$1/facelog-service/target/facelog-service-$project_version-standalone.jar"
    [ ! -f $jar_file ] && echo "没有找到目标jar包:$(basename $jar_file),$(basename $FACELOG_FOLDER) 项目需要编译" && exit 255

    echo "copy target file from $1/facelog-service to $folder"
    cp -rv "$1/db2/sql" $folder/ || exit 255
    cp -rv "$1/facelog-client-cpp/proxy" $folder/ || exit 255
    cp -v "$1/facelog-service/start_facelog_server.sh" $folder/ || exit 255
    cp -v "$1/facelog-service/start_facelog_server.bat" $folder/ || exit 255
    cp -v "$1/facelog-service/start_facelog_server_debug.sh" $folder/ || exit 255
    cp -v "$1/facelog-service/start_facelog_server_debug.bat" $folder/ || exit 255
    cp -v "$1/facelog-service/target/start_facelog_server.sh" $folder/target/ || exit 255
    cp -v "$1/facelog-service/target/start_facelog_server.bat" $folder/target/ || exit 255
    cp -v "$1/facelog-service/target/start_facelog_server_debug.sh" $folder/target/ || exit 255
    cp -v "$1/facelog-service/target/start_facelog_server_debug.bat" $folder/target/ || exit 255
    cp -v "$jar_file" $folder/target/ || exit 255
    [ $pushd_bash -eq 0 ] && popd >/dev/null
}

# 复制$1指定的fdevmgrWhse项目编译后的文件到当前项目文件夹
# $1 fdevmgrWhse项目源码位置
# $2 项目版本号
function fdevmgrWhse_copy(){
    local pushd_bash=1
    [ -d bash ] && pushd bash >/dev/null && pushd_bash=0
    local folder="fdevmgrWhse"
    # 从pom.xml中获取版本号
    local project_version=$2
    rm -fr "$folder" || exit 255
    if [ ! -d "$folder/target" ]
    then
        mkdir -p "$folder/target" || exit 255
    fi
    local jar_file="$1/target/fdevmgr-server-$project_version-standalone.jar"
    [ ! -f $jar_file ] && echo "没有找到目标jar包:$(basename $jar_file),$folder 项目需要编译" && exit 255
    echo "copy target file from $1/fdevmgrWhse to $folder"
    cp -rv "$1/src/main/resources/createTable" $folder/ || exit 255    
    cp -v "$1/start_fdevmgr_server.sh" $folder/ || exit 255
    cp -v "$1/start_fdevmgr_server.bat" $folder/ || exit 255
    cp -v "$1/target/start_fdevmgr_server.sh" $folder/target/ || exit 255
    cp -v "$1/target/start_fdevmgr_server.bat" $folder/target/ || exit 255
    cp -v "$jar_file" $folder/target/ || exit 255
    [ $pushd_bash -eq 0 ] && popd >/dev/null
}
# 复制$1指定的fdevmgrWhse-web项目编译后的文件到当前项目文件夹
# $1 fdevmgrWhse-web项目源码位置
# $2 项目版本号,可为空
function fdevmgrWhse_web_copy(){
    local pushd_bash=1
    [ -d bash ] && pushd bash >/dev/null && pushd_bash=0
    local folder="fdevmgrWhse-web"
    rm -fr "$folder" || exit 255
    if [ ! -d "$folder" ]
    then
        mkdir -p "$folder" || exit 255
    fi
    echo "copy target file from $1/dist to $folder"
    cp -fr "$1/dist/" $folder/ || exit 255
    cp -fr "$1/client/" $folder/ || exit 255
    [ $pushd_bash -eq 0 ] && popd >/dev/null
}

# 复制$1指定的webredis项目文件到当前项目文件夹
# $1 webredis项目源码位置
function webredis_copy(){
    local pushd_bash=1
    [ -d bash ] && pushd bash >/dev/null && pushd_bash=0
    local folder="webredis"
    rm -fr "$folder" || exit 255
    if [ ! -d "$folder/test" ]
    then
        mkdir -p "$folder/test" || exit 255
    fi
    echo "copy file from $1/webredis to $folder"
    cp -v "$1/config.js" $folder/ || exit 255
    cp -v "$1/LICENSE" $folder/ || exit 255
    cp -v "$1/package.json" $folder/ || exit 255
    cp -v "$1/webredis" $folder/ || exit 255
    cp -v "$1/webredis.service" $folder/ || exit 255
    cp -v "$1/webredis.js" $folder/ || exit 255
    cp -v "$1/test/index.html" $folder/test || exit 255
    [ $pushd_bash -eq 0 ] && popd >/dev/null
}
INIT_PRJ_LOCATION='
# facelog 项目本地位置
FACELOG_FOLDER=${FACELOG_FOLDER:=$sh_folder/../facelog}
# facelog 项目 git 仓库
FACELOG_REPO=${FACELOG_REPO:=https://gitee.com/l0km/facelog.git}
# webredis 项目本地位置
WEBREDIS_FOLDER=${WEBREDIS_FOLDER:=$sh_folder/../webredis}
# webredis 项目 git 仓库
WEBREDIS_REPO=${WEBREDIS_REPO:=https://gitee.com/l0km/webredis.git}
# fdevmgrWhse 项目本地位置
FDEVMGR_FOLDER=${FDEVMGR_FOLDER:=$sh_folder/../fdevmgrWhse}
# fdevmgrWhse 项目 git 仓库
FDEVMGR_REPO=${FDEVMGR_REPO:=https://gitee.com/zydltech/fdevmgrWhse.git}
# fdevmgrWhse-web 项目本地位置
FDEVMGRWEB_FOLDER=${FDEVMGRWEB_FOLDER:=$sh_folder/../fdevmgrWhse-web}
# fdevmgrWhse-web 项目 git 仓库
FDEVMGRWEB_REPO=${FDEVMGRWEB_REPO:=https://gitee.com/zydltech/fdevmgrWhse-web.git}'
function create_facelog_install_cfg_ifabsent(){
    [ -f $HOME/facelog-install.cfg ] && return 0
    echo "# 请根据项目实际位置修改各参数值
$INIT_PRJ_LOCATION" >$HOME/facelog-install.cfg || exit 255
}

# $1 ${PROJ}_FOLDER
# $2 ${PROJ}_REPO
function clone_git_repo_if_needed(){
    [ -d "$1" ] || { git clone "$2" "$1" || exit 255; }
    check_git_repo "$1"
}
# 显示命令行参数说明
usage() {
    echo "facelog编译脚本"
    echo "Usage:"
    echo "  build.sh [OPTION]... [PROJECT]... "
    echo "OPTION:"
    echo "    -b --build 执行项目编译，默认不执行"
    echo "    -h --help 输出帮助信息"
    echo "PROJECT:$ALL_BUILD_TASKS"
    echo "        []中为任务别名"
    exit 255
}
# 定义所有任务[]中为任务别名
ALL_BUILD_TASKS="facelog webredis fdevmgrWhse[fdevmgr] fdevmgrWhse-web[fdevmgrweb,fdevweb]"
build_tasks=
# 是否项目编译
BUILD_PROJECT=false
# 解析命令行参数
for opt in $*; do    
    case "$opt" in
        -b|--build) BUILD_PROJECT=true ;;
        -h|--help) usage;;
        *) 
        if [ -n "$(echo $ALL_BUILD_TASKS|grep -w $opt)" ]
        then
            build_tasks="$opt $build_tasks"
        else
            echo "无效参数 $opt."
            usage
        fi
        ;;
    esac
done

[ -z "$build_tasks" ] && build_tasks=$(echo $ALL_BUILD_TASKS | sed -E -e 's/\[\S+\]//g')
echo build_tasks=$build_tasks

# 如果有则加载配置文件
# 配置文件定义项目位置
create_facelog_install_cfg_ifabsent
. $HOME/facelog-install.cfg
# 用缺省值初始化facelog-install.cfg没有定义的值
eval "$INIT_PRJ_LOCATION"

[ -n "$(echo $build_tasks|grep -w facelog)" ] && \
    clone_git_repo_if_needed "$FACELOG_FOLDER"    "$FACELOG_REPO"
[ -n "$(echo $build_tasks|grep -w webredis)" ] && \
    clone_git_repo_if_needed "$WEBREDIS_FOLDER"   "$WEBREDIS_REPO"
[ -n "$(echo $build_tasks|grep -w -E 'fdevmgr|fdevmgrWhse')" ] && \
    clone_git_repo_if_needed "$FDEVMGR_FOLDER"    "$FDEVMGR_REPO"
[ -n "$(echo $build_tasks|grep -w -E 'fdevmgrweb|fdevweb|fdevmgrWhse-web')" ] && \
    clone_git_repo_if_needed "$FDEVMGRWEB_FOLDER" "$FDEVMGRWEB_REPO"

. ./make_dev.sh

# 项目编译准备
for task in $build_tasks; do    
    case "$task" in
        facelog)
            input_branch "$FACELOG_FOLDER"
            FACELOG_BRANCH=$input_branch_return
            echo FACELOG_BRANCH=$input_branch_return
            if [ -n "$(git --git-dir "$FACELOG_FOLDER/.git" --work-tree "$FACELOG_FOLDER" tag | grep -w $FACELOG_BRANCH)" ]
            then
                # 分支名为 tag 时就是版本号
                FACELOG_VERSION=${FACELOG_BRANCH##*-}
            else
                checkou_to_branch $FACELOG_BRANCH "$FACELOG_FOLDER"
                FACELOG_VERSION=$(pom_version $FACELOG_FOLDER)
                checkou_to_branch $checkou_to_branch_return "$FACELOG_FOLDER"
            fi
            echo FACELOG_VERSION=$FACELOG_VERSION
            ;;
        webredis)
            input_branch "$WEBREDIS_FOLDER"
            WEBREDIS_BRANCH=$input_branch_return
            echo WEBREDIS_BRANCH=$input_branch_return
            checkou_to_branch $WEBREDIS_BRANCH "$WEBREDIS_FOLDER"
            WEBREDIS_VERSION=$(node_prj_version $WEBREDIS_FOLDER)
            checkou_to_branch $checkou_to_branch_return "$WEBREDIS_FOLDER"
            echo WEBREDIS_VERSION=$WEBREDIS_VERSION
            ;;
        fdevmgrWhse|fdevmgr)
            input_branch "$FDEVMGR_FOLDER"
            FDEVMGR_BRANCH=$input_branch_return
            echo FDEVMGR_BRANCH=$input_branch_return
            checkou_to_branch $FDEVMGR_BRANCH "$FDEVMGR_FOLDER"
            FDEVMGR_VERSION=$(pom_version $FDEVMGR_FOLDER)
            checkou_to_branch $checkou_to_branch_return "$FDEVMGR_FOLDER"
            echo FDEVMGR_VERSION=$FDEVMGR_VERSION
            ;;
        fdevmgrWhse-web|fdevmgrweb|fdevweb)
            input_branch "$FDEVMGRWEB_FOLDER"
            FDEVMGRWEB_BRANCH=$input_branch_return
            echo FDEVMGRWEB_BRANCH=$input_branch_return
            checkou_to_branch $FDEVMGRWEB_BRANCH "$FDEVMGRWEB_FOLDER"
            FDEVMGRWEB_VERSION=$(node_prj_version $FDEVMGRWEB_FOLDER)
            checkou_to_branch $checkou_to_branch_return "$FDEVMGRWEB_FOLDER"
            echo FDEVMGRWEB_VERSION=$FDEVMGRWEB_VERSION
            ;;
        *) echo "无效任务名 $task." ; exit 255;;   
    esac
done

# 执行项目编译
for task in $build_tasks; do    
    case "$task" in
        facelog)
            # facelog要求JDK1.7以上版本，否则报错退出
            [ "$BUILD_PROJECT" = 'true' ] && ! $jdk7_available \
                && echo "JDK 1.7 OR above required(要求JDK1.7以上版本)" && exit 255

            [ "$BUILD_PROJECT" = 'true' ] && maven_build "$FACELOG_FOLDER" $FACELOG_BRANCH './shade-package.sh'
            facelog_copy "$FACELOG_FOLDER" $FACELOG_VERSION
            ;;
        webredis)
            webredis_copy $WEBREDIS_FOLDER
            ;;
        fdevmgrWhse|fdevmgr)
            # fdevmgr要求JDK1.8以上版本，否则报错退出
            [ "$BUILD_PROJECT" = 'true' ] && ! $jdk8_available \
                && echo "JDK 1.8 OR above required(要求JDK1.8以上版本)" && exit 255

            [ "$BUILD_PROJECT" = 'true' ] && maven_build "$FDEVMGR_FOLDER" $FDEVMGR_BRANCH './shade-package.sh'
            fdevmgrWhse_copy "$FDEVMGR_FOLDER" $FDEVMGR_VERSION
            ;;
        fdevmgrWhse-web|fdevmgrweb|fdevweb)
            [ "$BUILD_PROJECT" = 'true' ] && vue_build "$FDEVMGRWEB_FOLDER" $FDEVMGRWEB_BRANCH 'npm run build'
            fdevmgrWhse_web_copy $FDEVMGRWEB_FOLDER
            ;;
        *) echo "无效任务名 $task." ; exit 255;;
    esac
done

[ -n "$FACELOG_VERSION"    ] && set_value ./release.status 'FACELOG_VERSION'    "$FACELOG_VERSION"
[ -n "$WEBREDIS_VERSION"   ] && set_value ./release.status 'WEBREDIS_VERSION'   "$WEBREDIS_VERSION"
[ -n "$FDEVMGR_VERSION"    ] && set_value ./release.status 'FDEVMGR_VERSION'    "$FDEVMGR_VERSION"
[ -n "$FDEVMGRWEB_VERSION" ] && set_value ./release.status 'FDEVMGRWEB_VERSION' "$FDEVMGRWEB_VERSION"

popd > /dev/null
